package com.stockz.indicator.climaticVolume;

import java.util.List;

import com.stockz.core.model.Bar;
import com.stockz.core.util.BarUtil;
import com.stockz.core.util.BarUtil.BarValueType;
import com.stockz.indicator.Indicator;
import com.stockz.indicator.movingAverage.simple.SimpleMovingAverageIndicator;
import com.stockz.indicator.stochastics.StochasticsIndicator;


public class BullishClimaticVolumeIndicator implements Indicator<BullishClimaticVolumeIndicatorConfiguration> {

	private BullishClimaticVolumeIndicatorConfiguration configuration 
		= new BullishClimaticVolumeIndicatorConfiguration();
	

	private SimpleMovingAverageIndicator simpleMovingAverageIndicator = new SimpleMovingAverageIndicator();
	private StochasticsIndicator stochasticsIndicator = new StochasticsIndicator();
	private BarValueType barValueType = BarValueType.AVGPRICE;
	
	@Override
	public double getValue(List<Bar> barList) {
		int longSpan = configuration.getLongSpan();
		if(barList == null || barList.size() <= longSpan){
			return 0;
		}
		
		
		simpleMovingAverageIndicator.setBarValueType(BarValueType.VOLUME);
		double volumeSimpleMovingAverage = simpleMovingAverageIndicator.getValue(barList);
		double volume = barList.get(0).getVolume();
		
		stochasticsIndicator.getIndicatorConfiguration().setSpan(configuration.getShortSpan());
		stochasticsIndicator.setBarValueType(BarValueType.AVGPRICE);
		double stochastics = stochasticsIndicator.getValue(barList);
		if(stochastics < 1){
			stochastics = 1;
		}
		
		if(!configuration.isVolumeOnly()){
			simpleMovingAverageIndicator.getIndicatorConfiguration().setSpan(longSpan);
			simpleMovingAverageIndicator.setBarValueType(BarValueType.AVGTRADESIZE);
			double averageTradeSizeSimpleMovingAverage = simpleMovingAverageIndicator.getValue(barList);
			double averageTradeSize = BarUtil.getValue(barList.get(0),BarValueType.AVGTRADESIZE);
			
			
			
			
			return (volume*averageTradeSize)
					/(averageTradeSizeSimpleMovingAverage*
					
					volumeSimpleMovingAverage*
					stochastics);
		}else{
			return (volume/
					volumeSimpleMovingAverage*
					stochastics);
		}
	}
	
	@Override
	public double[] getValues(List<Bar> barList) {
		int longSpan = configuration.getLongSpan();
		if(barList == null || barList.size() <= longSpan){
			return new double[0];
		}
		
		simpleMovingAverageIndicator.getIndicatorConfiguration().setSpan(longSpan);
		simpleMovingAverageIndicator.setBarValueType(BarValueType.AVGTRADESIZE);
		double[] averageTradeSizeSimpleMovingAverage = simpleMovingAverageIndicator.getValues(barList);
		
		simpleMovingAverageIndicator.setBarValueType(BarValueType.VOLUME);
		double[] volumeSimpleMovingAverage = simpleMovingAverageIndicator.getValues(barList);
		
		stochasticsIndicator.getIndicatorConfiguration().setSpan(configuration.getShortSpan());
		stochasticsIndicator.setBarValueType(BarValueType.AVGPRICE);
		double[] stochastics = stochasticsIndicator.getValues(barList);
		
		double[] values = new double[barList.size()];
		for(int i = barList.size()-1; i >=0; i--){
			if(i >= barList.size() - longSpan - 1){
				values[i] = 0;
			}else{
				double averageTradeSize = BarUtil.getValue(barList.get(i),BarValueType.AVGTRADESIZE);
				double volume = barList.get(i).getVolume();
				if(stochastics[i] < 1){
					stochastics[i] = 1;
				}
				
				values[i] = (volume*averageTradeSize)
						/(averageTradeSizeSimpleMovingAverage[i]*
						volumeSimpleMovingAverage[i]*
						stochastics[i]);
			}
		}
		return values;
	}
	
	@Override
	public BullishClimaticVolumeIndicatorConfiguration getIndicatorConfiguration() {
		return configuration;
	}

	public BarValueType getBarValueType() {
		return barValueType;
	}

	public void setBarValueType(BarValueType barValueType) {
		this.barValueType = barValueType;
	}
}
